package Model.xml.protocols;

import Model.RefreshDaemon;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;

/**
 *
 * @author pieterc
 */
public class StatusNet implements Protocol, Serializable {

    private String username, password;
    private String apiName, apiURL;
    private ProtocolXML xmlHandler;
    private int access;

    public StatusNet(String name, String userURL, int access) {
        this.apiURL = userURL;
        this.apiName = name;
        this.xmlHandler = new StatusNetXML(this.apiName);
        this.access = access;
    }

    public StatusNet() {
        this.apiURL = "http://identi.ca/api/";
        this.apiName = "identi.ca";
        this.xmlHandler = new StatusNetXML(this.apiName);
        this.access = Protocol.READWRITE;
    }

    public void authenticate() {
        //I do not need anything to do here... do I?
    }

    public String getApiURL() {
        return apiURL;
    }

    public String getApiName() {
        return apiName;
    }

    public ProtocolXML getXMLHandler() {
        return xmlHandler;
    }

    public void loadStandardTimeline() {
        try {
            String s = getApiName() + ".xml";
            File f = new File(s);
            if (!f.exists()) {
                f.createNewFile();
            }
            BufferedInputStream in = new java.io.BufferedInputStream(new java.net.URL(this.apiURL + "/statuses/home_timeline/" + username + ".xml").openStream());
            java.io.FileOutputStream fos = new java.io.FileOutputStream(s);
            java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
            byte[] data = new byte[1024];
            int x = 0;
            while ((x = in.read(data, 0, 1024)) >= 0) {
                bout.write(data, 0, x);
            }
            bout.close();
            in.close();
        } catch (IOException ex) {
            Logger.getLogger(RefreshDaemon.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void postStatus(String message) {
        try {
            // vars
            String URL = apiURL + "statuses/update.xml";
            //set up params
            ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
            params.add(new BasicNameValuePair("source", "Catch Up"));
            params.add(new BasicNameValuePair("status", message));
            // prepare post
            DefaultHttpClient client = new DefaultHttpClient();
            HttpContext localContext = new BasicHttpContext();
            HttpPost httpPost = new HttpPost(URL);
            httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
            // set up authentication
            BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
            UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
            AuthScope scope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM);
            credsProvider.setCredentials(scope, creds);
            client.setCredentialsProvider(credsProvider);
            // execute
            org.apache.http.HttpResponse response = client.execute(httpPost, localContext);
        } catch (IOException ex) {
            Logger.getLogger(StatusNet.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public int getAccess() {
        return access;
    }

    public int getAuthenticationMethod() {
        return BASIC_AUTH;
    }

    public void setCredentials(Object... o) {
        this.username = (String) o[0];
        this.password = (String) o[1];
    }

    public Object getInfo() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
